using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using FrameWork.Source.Texture;
using FrameWork.Source.Animation_class;

namespace FrameWork.Source.Object_Classes
{
    class CObject
    {

        public Boomer.Source.FrameWork.Tag_Manager.TagManager.TAGGED Tag { get; set; }
        
        /// <summary>
        /// Get or set the position of this object.
        /// </summary>
        public Vector2 m_vec2Position { get; set; }

        /// <summary>
        /// Get or set the previous position of this object
        /// </summary>
        public Vector2 m_vec2PrevPosition { get; set; }

        /// <summary>
        /// Get or set frame width of this object
        /// </summary>
        public int m_iFrameWidth { get; set; }

        /// <summary>
        /// Get or set frame height of this object
        /// </summary>
        public int m_iFrameHeight { get; set; }

        /// <summary>
        /// Get or set real width of this object   
        /// </summary>
        public int m_iObjectWidth { get; set; }

        /// <summary>
        /// Get or set real height of this object
        /// </summary>
        public int m_iObjectHeight { get; set; }

        /// <summary>
        /// Get or set the deep of this object
        /// </summary>
        public float m_fDeep { get; set; }

        /// <summary>
        /// Get or set if this object colliable or not
        /// </summary>
        public bool m_isColliable { get; set; }

        /// <summary>
        /// Get or set if this object alive or not
        /// </summary>
        public bool m_isAlive { get; set; }

        /// <summary>
        /// Get or set if this object visible or not
        /// </summary>
        public bool m_isVisible { get; set; }

        /// <summary>
        /// Get instance of image texture of this object
        /// </summary>
        public CTexture m_texImage { get; protected set; }

        /// <summary>
        /// Get a bounding box of this object
        /// </summary>
        private Rectangle m_rectBoundBox { get; set; }

        /// <summary>
        /// Get a offset bounding box of this object
        /// </summary>
        private Rectangle m_rectOffsetBoundBox { get; set; }

        /// <summary>
        /// Get or set a sprite for this object
        /// </summary>
        protected CSprite m_pSprite { get; set; }


        /// <summary>
        /// Constructor of this class
        /// </summary>
        public CObject()
        {
            m_vec2Position = Vector2.Zero;
            m_vec2PrevPosition = Vector2.Zero;
            m_iObjectWidth = 0;
            m_iObjectHeight = 0;
            m_iFrameWidth = 0;
            m_iFrameHeight = 0;
            m_fDeep = 0.0f;
            m_isAlive = true;
            m_isColliable = true;
            m_isVisible = true;
            m_texImage = null;
            m_rectBoundBox = Rectangle.Empty;
            m_rectOffsetBoundBox = Rectangle.Empty;
            m_pSprite = null;
        }

        /// <summary>
        /// Set Size of this object
        /// </summary>
        /// <param name="objWidth">Object width</param>
        /// <param name="objHeight">Object height</param>
        public void setSize(int objWidth, int objHeight)
        {
            m_iObjectWidth = m_iFrameWidth = objWidth;
            m_iObjectHeight = m_iFrameHeight = objHeight;
            m_rectBoundBox = new Rectangle(0, 0, m_iObjectWidth, m_iObjectHeight);
        }

        /// <summary>
        /// Set instance of texture image for this object
        /// </summary>
        /// <param name="pImage">Pointer to the texture image</param>
        /// <param name="imageWidth">Image width</param>
        /// <param name="imageHeight">Image heigh</param>
        public void setImage(CTexture pImage , int imageWidth , int imageHeight)
        {
            m_pSprite = new CSprite();
            m_pSprite.m_pImage = pImage;
            setSize(imageWidth, imageHeight);
        }

        /// <summary>
        /// Get a sprite instance of this object
        /// </summary>
        /// <returns></returns>
        public CSprite getSprite()
        {
            return m_pSprite;
        }

        /// <summary>
        /// Create a new bounding box
        /// </summary>
        /// <param name="offsetLeft">Offset from left of the image</param>
        /// <param name="offsetTop">Offset from top of the image</param>
        /// <param name="boundWith">Width of this bounding box</param>
        /// <param name="boundHeight">Height of this bounding box</param>
        public void createBoundBox(float offsetLeft, float offsetTop, int boundWith, int boundHeight)
        {
            m_rectOffsetBoundBox = new Rectangle((int)offsetLeft, (int)offsetTop, boundWith, boundHeight);
            m_iObjectWidth = boundWith;
            m_iObjectHeight = boundHeight;
        }

        /// <summary>
        /// Create new bounding box
        /// </summary>
        /// <param name="offsetLeft">Offset from left of the image</param>
        /// <param name="offsetTop">Offset from top of the image</param>
        /// <param name="offsetRight">Offset from right of the image</param>
        /// <param name="offsetBot">Offset from bottom of the image</param>
        public void createBoundBox(float offsetLeft, float offsetTop, float offsetRight, float offsetBot)
        {
            m_rectOffsetBoundBox = new Rectangle((int)offsetLeft, (int)offsetTop, (int)(offsetRight - offsetLeft), (int)(offsetBot - offsetTop));
            m_iObjectWidth = (int)(offsetRight - offsetLeft);
            m_iObjectHeight = (int)(offsetBot - offsetTop);
        }



        /// <summary>
        /// Move our object by a given amount
        /// </summary>
        /// <param name="dx">Amount X</param>
        /// <param name="dy">Amount Y</param>
        public void Move(float dx, float dy)
        {
            m_vec2PrevPosition = m_vec2Position;
            m_vec2Position += new Vector2(dx, dy);
        }


        public virtual void init()
        {

        }

        /// <summary>
        /// Update our object
        /// </summary>
        /// <param name="deltaTime"></param>
        public virtual void update(float deltaTime)
        {

        }

        /// <summary>
        /// Draw our object into screen
        /// </summary>
        public virtual void draw()
        {
            if (m_isVisible)
                m_pSprite.draw(m_vec2Position , m_fDeep , new Rectangle(0,0,m_iFrameWidth,m_iFrameHeight));
        }


        /// <summary>
        /// Get the bounding box of this object
        /// </summary>
        /// <returns></returns>
        public virtual Rectangle getBoundBox()
        {
            m_rectBoundBox = new Rectangle((int)m_vec2Position.X + m_rectOffsetBoundBox.X, (int)m_vec2Position.Y + m_rectOffsetBoundBox.Y, m_iObjectWidth, m_iObjectHeight);

            return m_rectBoundBox;
        }


        /// <summary>
        /// Collision checking with other object
        /// </summary>
        /// <param name="pObj">Another Object that this object collide with </param>
        /// <returns>true if collide , false if not</returns>
        public virtual bool Collision(ref CObject pObj)
        {
            if (this.getBoundBox().Intersects(pObj.getBoundBox()))
                return true;

            return false;
        }
    }
}
